﻿Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading.Tasks
Imports System.ComponentModel
Imports System.Threading

Public Class frmMain
    Private _Listener As TcpListener
    Public Shared _Connections As List(Of Connections)
    Public _ConnectionMonitor As Task
    Private _nMessages As String
    Private _queryLock As Boolean = False
    Private doAddListMsg As New Action(Of String)(AddressOf Console_Append)
    Private doAddListCon As New Action(Of String)(AddressOf AddListConn)
    Public Shared listConnected As New ListBox

    Private msgQueue_Resender As Task, tsMsgQueue As CancellationTokenSource

    ' CLASS FOR CONTROLLING SOCKETS
    Public Class Connections
        Public WithEvents Sockets As ConnectionInfo
        Public isAllowedToConnect As Boolean
        Public uid As String = ""
        Public userID As String = ""
        Public userNick As String = ""
        Public userSID As String = ""
        Public ConnectionTask As Task, tsConnectionTask As CancellationTokenSource
        Private counter As Integer = 0
        Private Shared mData As DataTable

        Sub New(info As ConnectionInfo)
            Sockets = info
            isAllowedToConnect = False
            tsConnectionTask = New CancellationTokenSource
            ConnectionTask = Task.Factory.StartNew(AddressOf SockMonitor, tsConnectionTask.Token)
        End Sub

        Private Sub SockMonitor()
            Do
                Try
                    If tsConnectionTask.Token.IsCancellationRequested Then Exit Sub

                    If Sockets.Sock.Connected Then
                        If Sockets.Sock.Poll(1000, SelectMode.SelectRead) = False Or (Sockets.Sock.Poll(1000, SelectMode.SelectWrite) = True And Sockets.Sock.Poll(1000, SelectMode.SelectError) = False) Then
                            Dim buffer() As Byte = New Byte(1) {}
                            Try
                                If Sockets.Sock.Receive(buffer, SocketFlags.Peek) = 0 Then
                                    Sockets.isConnected = False
                                Else
                                    Sockets.isConnected = True
                                End If
                            Catch ex As SocketException
                                Sockets.isConnected = True
                            End Try
                        Else
                            Sockets.isConnected = False
                        End If
                    Else
                        Sockets.isConnected = False
                    End If

                    ConnectionTask.Wait(500)
                Catch ex As Exception
                    Try
                        If Sockets.Sock.Connected Then
                            Sockets.isConnected = True
                        End If
                    Catch exc As Exception
                        Sockets.isConnected = False
                        Exit Sub
                    End Try
                End Try

            Loop While 1
        End Sub

        Private Sub Sockets_onMessageArrived(msg As String) Handles Sockets.onMessageArrived
            Dim data() As String = Split(Split(msg, Packet.pEof, -1, CompareMethod.Text)(0), Packet.pSplit, -1, CompareMethod.Text)
            Select Case data(0)
                Case "1"
                    If data.Length >= 3 Then
                        If mysql_isconnected(True) Then
                            mData = mysql_query("SELECT * FROM tb_user WHERE BINARY user='" & data(1) & "' AND BINARY passw=MD5('" & data(2) & "') LIMIT 1")
                            If mData.Rows.Count > 0 Then
                                Dim isAbleLogin As Boolean = True
                                isAllowedToConnect = True

                                For Each client As Connections In _Connections
                                    If userID.Equals("") = True And data(1).Equals(client.userID) And Sockets.Equals(client.Sockets) Then
                                        Sockets.SendMessage("1" & Packet.pSplit & "1")
                                        Sockets.Client.Close()
                                        isAbleLogin = False
                                        Exit Sub
                                    ElseIf userID.Equals("") = True And data(1).Equals(client.userID) Then
                                        'Sockets.SendMessage("255" & Packet.pSplit & "1")
                                        'client.Sockets.Client.Close()
                                        Sockets.SendMessage("1" & Packet.pSplit & "2")
                                        Sockets.Client.Close()
                                        '''''''''''''''
                                        isAbleLogin = False
                                        Exit For
                                    End If
                                Next

                                If isAbleLogin Then
                                    uid = mData.Rows(0)("id")
                                    userID = mData.Rows(0)("user")
                                    userNick = mData.Rows(0)("nickname")
                                    userSID = vbNull
                                    mForm.Invoke(mForm.doAddListCon, Sockets.Client.Client.RemoteEndPoint.ToString)
                                    mForm.Invoke(New Action(AddressOf mForm.setListConn))
                                    mForm.Invoke(mForm.doAddListMsg, "A Client has Been Connected | IP: " + Sockets.Client.Client.RemoteEndPoint.ToString)
                                    mysql_non_query("UPDATE tb_user SET is_login='1' WHERE id='" & uid & "'")
                                    Dim updateIP As Boolean = mysql_non_query("UPDATE tb_user SET ipv4='" & Split(Sockets.Client.Client.RemoteEndPoint.ToString, ":")(0) & "' WHERE user='" & userID & "'")
                                    Sockets.SendMessage("1" & Packet.pSplit & "0" & Packet.pSplit & userID & Packet.pSplit & userNick)
                                End If
                            Else
                                Sockets.SendMessage("1" & Packet.pSplit & "9")
                                Sockets.Client.Close()
                            End If
                        Else
                            Sockets.SendMessage("1" & Packet.pSplit & "6")
                            Sockets.Client.Close()
                        End If
                    Else
                        isAllowedToConnect = False
                        Sockets.SendMessage("0xFF" & Packet.pSplit & "0xFF")
                        Sockets.Client.Close()
                    End If
                Case "10" 'User Requested to Change Their User Data
                    If isAllowedToConnect Then
                        If data.Length >= 2 Then
                            Select Case data(1)
                                Case "1"
                                    'Client Requesting User Data
                                    Sockets.SendMessage("10" & Packet.pSplit & "1" & Packet.pSplit & userNick)
                                Case "2"
                                    'Client Requesting Data Change
                                    Dim singleDB As New Databases
                                    'Index 2: Old Password
                                    'Index 3: New Password
                                    'Index 4: Confirm New Password
                                    'Index 5: Nickname
                                    If data(2).Equals("") = False And data(5).Equals("") = False Then
                                        mData = singleDB.mysql_query(String.Format("SELECT * FROM tb_user WHERE user='{0}' AND passw=MD5('{1}') LIMIT 1", userID, data(2)))
                                        If mData.Rows.Count > 0 Then
                                            'If Client Fill New Password
                                            If data(3).Equals("") = False Or data(4).Equals("") = False Then
                                                If data(3).Equals(data(4)) Then
                                                    If singleDB.mysql_non_query(String.Format("UPDATE tb_user SET passw='{0}', nickname='{1}' WHERE id='{2}'", data(3), data(5), mData.Rows(0)("id"))) Then
                                                        mData = singleDB.mysql_query(String.Format("SELECT * FROM tb_user WHERE user='{0}' AND passw=MD5('{1}') LIMIT 1", userID, data(3)))
                                                        uid = mData.Rows(0)("id")
                                                        userID = mData.Rows(0)("user")
                                                        userNick = mData.Rows(0)("nickname")
                                                        Sockets.SendMessage("10" & Packet.pSplit & "2" & Packet.pSplit & "0" & Packet.pSplit & mData.Rows(0)("nickname"))
                                                    Else
                                                        Sockets.SendMessage("10" & Packet.pSplit & "2" & Packet.pSplit & "1")
                                                    End If
                                                Else
                                                    'New Password and Confirmation Does Not Match
                                                    Sockets.SendMessage("10" & Packet.pSplit & "2" & Packet.pSplit & "2")
                                                End If

                                            Else
                                                If singleDB.mysql_non_query(String.Format("UPDATE tb_user SET nickname='{0}' WHERE id='{1}'", data(5), mData.Rows(0)("id"))) Then
                                                    mData = singleDB.mysql_query(String.Format("SELECT * FROM tb_user WHERE user='{0}' AND passw=MD5('{1}') LIMIT 1", userID, data(2)))
                                                    uid = mData.Rows(0)("id")
                                                    userID = mData.Rows(0)("user")
                                                    userNick = mData.Rows(0)("nickname")
                                                    Sockets.SendMessage("10" & Packet.pSplit & "2" & Packet.pSplit & "0" & Packet.pSplit & mData.Rows(0)("nickname"))
                                                Else
                                                    Sockets.SendMessage("10" & Packet.pSplit & "2" & Packet.pSplit & "1")
                                                End If
                                            End If
                                        Else
                                            'User Not Found
                                            Sockets.SendMessage("10" & Packet.pSplit & "2" & Packet.pSplit & "3")
                                        End If
                                    Else
                                        'Form Still Empty
                                        Sockets.SendMessage("10" & Packet.pSplit & "2" & Packet.pSplit & "4")
                                    End If

                                Case Else
                                    Sockets.SendMessage("0xFF" & Packet.pSplit & "0xFF")
                            End Select
                        End If
                    End If
                Case "100" 'User Send Messages
                    counter = 0
                    Dim specialChar As String = String.Empty
                    Dim tmpstr As String = String.Empty
                    Dim tmpQueue As String = String.Empty
                    If isAllowedToConnect Then
                        'Check Multi Message Splitted
                        specialChar = String.Empty
                        tmpstr = String.Empty
                        If data.Length > 3 Then
                            tmpstr = Packet.pSplit
                            For k As Integer = 3 To data.Length - 1
                                tmpstr = tmpstr & data(k).ToString
                                If k < data.Length - 1 Then
                                    tmpstr = tmpstr & Packet.pSplit
                                End If
                            Next
                            'Jika ada /callback di depan teks maka kembalikan pesan jika kontak tidak ada atau tidak online
                            If data(2).Equals("/callback") Then
                                specialChar = tmpstr
                                data(2) = String.Empty
                            End If
                        End If
                        '---End Check

                        For Each client As Connections In _Connections
                            If data(1).Equals(client.userID) Then 'And data(1).Equals(userID) = False Then
                                counter = 1
                                If data(2).Equals(String.Empty) = False Then
                                    data(2) = Packet.pSplit & data(2)
                                End If

                                Try
                                    client.Sockets.SendMessage("100" & Packet.pSplit & userID & data(2) & tmpstr)
                                Catch ex As Exception
                                    tmpQueue = data(2) & tmpstr
                                    If tmpQueue.IndexOf(Packet.pSplit) = 0 Then
                                        tmpQueue = tmpQueue.Substring(0 + Packet.pSplit.Length)
                                    End If
                                    mysql_non_query(String.Format("INSERT INTO tb_msg_queue(`message`,`from`,`to`,`status`) VALUES ('{0}','{1}','{2}','{3}')", tmpQueue, userID, data(1), "0"))
                                End Try

                                Exit For
                            End If

                            'If data(1).Equals(userID) = True Then
                            'counter = 1
                            'End If
                        Next

                        ' No Target Online
                        If counter = 0 Then
                            Console.WriteLine(specialChar)
                            If mysql_isconnected(True) Then
                                mData = mysql_query("SELECT * FROM tb_user WHERE BINARY user='" & data(1) & "' LIMIT 1")
                                If mData.Rows.Count <= 0 Then
                                    Sockets.SendMessage("100" & Packet.pSplit & "Server" & Packet.pSplit & "/responseunknowncontact" & specialChar)
                                Else
                                    tmpQueue = data(2) & tmpstr
                                    If tmpQueue.IndexOf(Packet.pSplit) = 0 Then
                                        tmpQueue = tmpQueue.Substring(0 + Packet.pSplit.Length)
                                    End If
                                    mysql_non_query(String.Format("INSERT INTO tb_msg_queue(`message`,`from`,`to`,`status`) VALUES ('{0}','{1}','{2}','{3}')", tmpQueue, userID, data(1), "0"))
                                    If specialChar.Equals("") Then
                                        Sockets.SendMessage("100" & Packet.pSplit & "Server" & Packet.pSplit & "/responseofflinecontact" & specialChar)
                                    End If
                                End If
                            Else
                                tmpQueue = data(2) & tmpstr
                                If tmpQueue.IndexOf(Packet.pSplit) = 0 Then
                                    tmpQueue = tmpQueue.Substring(0 + Packet.pSplit.Length)
                                End If
                                mysql_non_query(String.Format("INSERT INTO tb_msg_queue(`message`,`from`,`to`,`status`) VALUES ('{0}','{1}','{2}','{3}')", tmpQueue, userID, data(1), "0"))

                                Sockets.SendMessage("100" & Packet.pSplit & "Server" & Packet.pSplit & "/responseofflinecontact" & specialChar)

                            End If
                        End If
                    End If
                Case Else
                    isAllowedToConnect = False
                    Sockets.SendMessage("0xFF" & Packet.pSplit & "0xFF")
                    Sockets.Client.Close()
            End Select
        End Sub
    End Class
    '=== END SOCKET CONTROL ===

    '=============================================================
    ' Invoke Fungsi Objek Agar Dapat Digunakan Di Protected Class
    '=============================================================

    Public Sub setListConn()
        clientMonitor.lstConnected.Items.Clear()
        For lists As Integer = 0 To listConnected.Items.Count - 1
            clientMonitor.lstConnected.Items.Add(listConnected.Items.Item(lists))
        Next
    End Sub

    Public Sub AddListConn(messages As String)
        'clientMonitor.lstConnected.Items.Add(messages)
        listConnected.Items.Add(messages)
    End Sub

    Public Sub RemoveListConn(idx As String)
        'clientMonitor.lstConnected.Items.RemoveAt(Convert.ToInt32(idx))
        listConnected.Items.RemoveAt(Convert.ToInt32(idx))
    End Sub

    Private Sub frmMain_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        notifyMaster.Dispose()
    End Sub
    '===============================================================================================

    '===============================================================================================
    ' Kumpulan Kode Untuk EVENT Object
    '===============================================================================================

    ' Form Load
    Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.WindowState = FormWindowState.Minimized
        Me.ShowInTaskbar = False
        notifyMaster.ShowBalloonTip(1000)
        mForm = Me
        If System.IO.File.Exists(My.Application.Info.DirectoryPath.ToString & "\server.xml") = False Then
            client_write_configuration()
        Else
            client_read_configuration()
            If auto_start = True Then
                iConnect.PerformClick()
            End If
        End If
    End Sub

    Public Sub setNotifyBaloon(ByVal title As String, ByVal messages As String, ByVal icon As System.Windows.Forms.ToolTipIcon)
        notifyMaster.BalloonTipIcon = icon
        notifyMaster.BalloonTipTitle = title
        notifyMaster.BalloonTipText = messages
        notifyMaster.ShowBalloonTip(500)
    End Sub
    '======================================================================================

    Private Sub ListenForClient()
        Dim info As New ConnectionInfo(_Listener)
        _Listener.BeginAcceptTcpClient(AddressOf DoAcceptClient, info)
    End Sub

    Private Sub DoAcceptClient(result As IAsyncResult)
        Try
            If _Listener IsNot Nothing Then
                Dim info As ConnectionInfo = CType(result.AsyncState, ConnectionInfo)
                Dim Conn As Connections = New Connections(info)
                info.AcceptClient(result)
                ListenForClient()

                info.AwaitData()
                _Connections.Add(Conn)
            End If
        Catch ex As Exception
            Console.WriteLine("DoAcceptClient : " + ex.Message)
        End Try
    End Sub

    Public Function msgToByte(ByVal msg As String) As Byte()
        Return System.Text.Encoding.ASCII.GetBytes(msg + Packet.pEof)
    End Function

    Private Sub DoResendQueue()
        Dim obj As Object
        Dim t_queue As DataTable
        Dim t_loginstat As DataTable
        Do
            Try
                ' If Cancellation Token is Set Then Stop Task
                If tsMsgQueue.Token.IsCancellationRequested = True Then
                    Console.WriteLine("Queue Resend Task Cancelled")
                    Exit Do
                End If

                obj = mysql_query("SELECT * FROM tb_msg_queue ORDER BY timestamp ASC")

                If Type.GetTypeCode(obj.GetType) <> TypeCode.Boolean Then
                    t_queue = obj
                    For Each rows As DataRow In t_queue.Rows
                        obj = mysql_query("SELECT * FROM tb_user WHERE user='" & rows("to") & "' LIMIT 1")
                        If Type.GetTypeCode(obj.GetType) <> TypeCode.Boolean Then
                            t_loginstat = obj
                            If t_loginstat.Rows(0)("is_login").Equals(True) Then
                                For Each Conn As Connections In _Connections
                                    If Conn.userID.Equals(rows("to")) Then
                                        If Conn.Sockets.Client.Connected And Conn.Sockets.isConnected Then
                                            Try
                                                Conn.Sockets.SendMessage(String.Format("100{0}{1}{0}{2}", Packet.pSplit, rows("from"), rows("message")))
                                                obj = mysql_non_query("DELETE FROM tb_msg_queue WHERE id='" & rows("id") & "'")
                                            Catch ex As Exception

                                            End Try
                                            msgQueue_Resender.Wait(500)
                                        Else
                                            Try
                                                mysql_non_query("UPDATE tb_user SET is_login='0' WHERE id='" & Conn.uid & "'")
                                            Catch ex As Exception
                                                Console.WriteLine("DoResendQueue_1: " + ex.Message)
                                            End Try
                                        End If
                                    End If
                                Next
                                
                            End If
                        End If
                    Next
                End If
            Catch ex As Exception
                Console.WriteLine("DoResendQueue_2: " + ex.Message)
            End Try
            msgQueue_Resender.Wait(500)
        Loop While 1
    End Sub

    Private Sub DoMonitorConnections()
        Dim doRemoveList As New Action(Of String)(AddressOf RemoveListConn)
        Me.Invoke(doAddListMsg, "Server Started")
        Me.Invoke(Sub() setNotifyBaloon("Synchronization Server", "Server Telah Berjalan", ToolTipIcon.Info))
        ToolStripMenuItemConnect.Text = "Disconnect"
        msgQueue_Resender = Task.Factory.StartNew(AddressOf DoResendQueue, tsMsgQueue.Token)
        Do
            Try
                ' Cek Semua Socket dalam Variabel info

                For Each Conn As Connections In _Connections

                    If Conn.Sockets.Client.Connected And Conn.Sockets.isConnected Then
                        '===================================================
                        ' Proses Setiap Client Yang Terhubung

                        ' CEK LOGIN SESSION --

                        ' END SESSION CHECK --
                    Else
                        If Conn.ConnectionTask.Status = TaskStatus.Running Then
                            Conn.tsConnectionTask.Cancel()
                            Conn.ConnectionTask.Wait()
                        End If

                        _Connections.Remove(Conn)
                        For numLst As Integer = 0 To listConnected.Items.Count - 1
                            If listConnected.Items.Item(numLst).ToString.Equals(Conn.Sockets._ipport) Then
                                Me.Invoke(doRemoveList, numLst.ToString)
                                Me.Invoke(doAddListMsg, Conn.Sockets._ipport + " Disconnected")
                                mysql_non_query("UPDATE tb_user SET is_login='0' WHERE id='" & Conn.uid & "'")
                                _Connections.Remove(Conn)
                                Exit For
                            End If
                        Next
                        Me.Invoke(New Action(AddressOf setListConn))
                        Exit For
                    End If
                Next
            Catch ex As Exception
                Console.WriteLine("DoMonitorConnection: " + ex.Message)
            End Try
            _ConnectionMonitor.Wait(1000)
        Loop While Not iConnect.Caption.Equals("Start")

        ToolStripMenuItemConnect.Text = "Connect"
        Me.Invoke(Sub() setNotifyBaloon("Synchronization Server", "Server Telah Dihentikan", ToolTipIcon.Warning))
        Me.Invoke(doAddListMsg, "Server Has Stop Listening")
        iConnect.LargeImageIndex = 10
        iConnect.Enabled = True
        tsMsgQueue.Cancel()
    End Sub


    Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs)
        Me.Close()
    End Sub


    Private Sub iConnect_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles iConnect.ItemClick

        If iConnect.Caption.Equals("Start") Then
            'Dim HostEntry As IPHostEntry = Dns.GetHostAddresses
            Dim ipAddr As IPAddress() = Dns.GetHostAddresses(listen_host) 'HostEntry.AddressList
            Dim i As Integer = 0
            Dim indexTmp As String = -1

            For i = 0 To ipAddr.Count - 1
                Select Case ipAddr(i).AddressFamily
                    Case System.Net.Sockets.AddressFamily.InterNetwork
                        If indexTmp = -1 Then
                            indexTmp = i
                        End If
                        If ipAddr(i).ToString.Equals(listen_host) Then
                            Exit For
                        End If
                End Select
                If indexTmp > -1 And i >= ipAddr.Count - 1 Then
                    i = indexTmp
                    Exit For
                End If
            Next

            Try
                iConnect.Caption = "Stop"
                _Connections = New List(Of Connections)
                _Listener = New TcpListener(ipAddr(i), listen_port)
                _Listener.Start()

                _ConnectionMonitor = Task.Factory.StartNew(AddressOf DoMonitorConnections, TaskCreationOptions.LongRunning)
                ListenForClient()
                Console_Append("Listening on - IP: " & ipAddr(i).ToString & " | Port: " & listen_port)
                iConnect.LargeImageIndex = 20
                ToolStripMenuItemConnect.Text = "Disconnect"
                tsMsgQueue = New CancellationTokenSource
            Catch ex As Exception
                Console_Append("Failed to listen on - IP: " & ipAddr(i).ToString & " | Port: " & listen_port)
                iConnect.Caption = "Start"
                iConnect.LargeImageIndex = 10
            End Try
        Else

            _Listener.Stop()

            For Each client As Connections In _Connections
                Try
                    client.Sockets.Client.Close()
                Catch ex As Exception

                End Try
            Next

            _Connections.Clear()
            _Connections = Nothing

            listConnected.Items.Clear()
            Console_Append("Stopping Server..")
            iConnect.Caption = "Start"
            iConnect.LargeImageIndex = 10
            iConnect.Enabled = False
            ToolStripMenuItemConnect.Text = "Connect"
        End If

    End Sub

    Private Sub iConnectedUser_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles iConnectedUser.ItemClick
        setListConn()
        clientMonitor.Show()
    End Sub

    Private Sub Console_Append(ByVal msg As String)
        If txtConsole.Lines.Length > 500 Then txtConsole.Text = ""

        If txtConsole.Text.Length = 0 Then
            txtConsole.AppendText("> " & msg)
        Else
            txtConsole.AppendText(msg)
        End If

        txtConsole.ScrollToCaret()
        If txtConsole.Text.Length > 0 Then
            txtConsole.AppendText(ControlChars.NewLine)
            txtConsole.AppendText("> ")
        End If
    End Sub

    Private Sub iDatabaseConfig_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles iDatabaseConfig.ItemClick
        frmDBOption.ShowDialog()
    End Sub

    Private Sub iSystemConfig_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles iSystemConfig.ItemClick
        frmAppConfig.ShowDialog()
    End Sub

    Private Sub iShutdown_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles iShutdown.ItemClick
        Me.Close()
    End Sub

    Private Sub iUserManage_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles iUserManage.ItemClick
        frmUser.Show()
    End Sub

    Private Sub frmMain_Resize(sender As Object, e As EventArgs) Handles Me.Resize
        Try
            If Me.WindowState = FormWindowState.Minimized Then
                ToolStripMenuItemDashboard.Text = "Dashboard"
                Me.WindowState = FormWindowState.Minimized
                Me.ShowInTaskbar = False
                Me.Hide()
            End If
        Catch ex As Exception

        End Try
    End Sub

    Private Sub ToolStripMenuItemDashboard_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItemDashboard.Click
        If ToolStripMenuItemDashboard.Text = "Dashboard" Then
            ToolStripMenuItemDashboard.Text = "Hide"
            Me.Show()
            Me.ShowInTaskbar = True
            Me.WindowState = FormWindowState.Normal
        Else
            ToolStripMenuItemDashboard.Text = "Dashboard"
            Me.WindowState = FormWindowState.Minimized
            Me.ShowInTaskbar = False
            Me.Hide()
        End If
    End Sub

    Private Sub notifyMaster_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles notifyMaster.MouseDoubleClick
        If ToolStripMenuItemDashboard.Text = "Dashboard" Then
            ToolStripMenuItemDashboard.Text = "Hide"
            Me.Show()
            Me.ShowInTaskbar = True
            Me.WindowState = FormWindowState.Normal
        End If
    End Sub

    Private Sub ToolStripMenuItemConnect_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItemConnect.Click
        iConnect.PerformClick()
    End Sub

    Private Sub ToolStripMenuItemExit_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItemExit.Click
        Me.Close()
    End Sub

    Private Sub ToolStripMenuItemClearConsole_DoubleClick(sender As Object, e As EventArgs) Handles ToolStripMenuItemClearConsole.DoubleClick
        txtConsole.Text = "> "
        txtConsole.Select(txtConsole.TextLength, 0)
    End Sub

    Private Sub txtConsole_MouseDown(sender As Object, e As MouseEventArgs) Handles txtConsole.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Right Then
            ContextMenuRightConsole.Show(txtConsole, New Point(e.X, e.Y))
        End If
    End Sub
End Class
